/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.common.util;

import com.google.common.collect.Sets;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Set;

/**
 * 异常工具类
 *
 * @author vacoor
 */
@SuppressWarnings({"unused"})
public abstract class Throwables {

    /**
     * 检查异常是否由给定异常引发
     */
    public static boolean causedBy(Throwable t, Class<? extends Throwable> causeType) {
        Set<Throwable> causes = Sets.newHashSet();

        for (; t != null && !causeType.isInstance(t) && !causes.contains(t); t = t.getCause()) {
            causes.add(t);
        }

        return t != null && causeType.isInstance(t);
    }

    public static RuntimeException unchecked(Throwable t) {
        return unchecked(t, RuntimeException.class);
    }

    /**
     * 如果给定异常不是 unchecked 异常, 则转换为给定 unchecked 异常, 否则返回原 unchecked 异常
     *
     * @param t
     * @param uncheckedType 如果为null, 则等价于RuntimeException
     * @return
     */
    public static RuntimeException unchecked(Throwable t, Class<? extends RuntimeException> uncheckedType) {
        if (t instanceof RuntimeException) {
            return (RuntimeException) t;
        }

        if (uncheckedType == null) {
            return new RuntimeException(t);
        }

        RuntimeException e;
        try {
            e = uncheckedType.newInstance();
        } catch (Exception e1) {
            return new RuntimeException(t);
        }
        e.initCause(t);

        return e;
    }

    public static String getStackTraceAsString(Throwable t) {
        StringWriter writer = new StringWriter();
        t.printStackTrace(new PrintWriter(writer));

        return writer.toString();
    }

    private Throwables() {
    }
}
